package com.google.code.mergeinformer.controller;

import com.google.code.mergeinformer.model.Project;
import com.google.code.mergeinformer.util.Measured;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;

/**
 * Handles requests for the application HOME_VIEW page.
 */
@Controller
public class HomeController extends ControllerBase {

    public static final String HOME_VIEW = "index";

    @Autowired
    private ExecutorService executorService;

    @RequestMapping("/")
    public String home() {
        setCurrent(null, null);
        return HOME_VIEW;
    }

    @RequestMapping(value = "/", params = "execute")
    public String executeAllProjects() {
        final List<Project> projects = new LinkedList<>();
        final long elapsed = new Measured() {
            @Override
            protected void measuredBlock() {
                projects.addAll(projectService.getAllProjects());
                final List<Callable<Void>> projectRunners = new ArrayList<>(projects.size());
                for (final Project project : projects) {
                    projectRunners.add(new Callable<Void>() {
                        @Override
                        public Void call() throws Exception {
                            projectService.execute(project);
                            return null;
                        }
                    });
                }
                try {
                    executorService.invokeAll(projectRunners);
                } catch (InterruptedException ignored) {
                }
            }
        }.execute();

        int totalTasks = 0;
        int failedTasks = 0;
        for (Project project : projects) {
            totalTasks += project.getTasks().size();
            failedTasks += project.getFailedTasksCount();
        }

        final String title = "Update all projects";
        final Notification notification;
        if (failedTasks == 0) {
            notification = buildNotification(
                    Notification.Type.success,
                    title,
                    "All <b>" + totalTasks + " tasks</b> in <b>" + projects.size() + " projects</b> were successfully updated",
                    elapsed
            );
        } else if (failedTasks < totalTasks) {
            notification = buildNotification(
                    Notification.Type.notice,
                    title,
                    "<b>" + failedTasks + "</b> of <b>" + totalTasks + " tasks</b> in <b>" + projects.size()
                            + " projects</b> were failed",
                    elapsed
            );
        } else {
            notification = buildNotification(
                    Notification.Type.error,
                    title,
                    "All <b>" + failedTasks + " tasks</b> in <b>" + projects.size() + " projects</b> were failed",
                    elapsed
            );
        }

        pushNotifications(notification);

        return getRedirect();
    }

}
